//Extra Credit
template<class itr, class func1, class func2>
void MTAData::perform_if(itr begin, itr end, func1 pred, func2 op){
	//Pred must be a unary predicate accepting a trainStopData* and op must be an operation accepting a trainStopData*
	while(begin != end){
		if (pred(*begin))
		{
			op(*begin);
		}
		++begin;
	}
}

template<class UTSDP>
std::list<std::string> MTAData::hereToThere(const std::string& a, UTSDP pred){
	std::queue<std::string> q;
	std::map<std::string, std::pair<std::string, int> > prevMap;	//key is the stop ID, pair1 is previuos id, pair2 is distance from a
	//add a's adj list
	q.push(a);
	prevMap[a] = std::pair<std::string, int>("", 0);
	std::string found;
	//loop over q adding THIER adj lists until I have visited a good place
	while(!q.empty()){
		//is this b?
		//break
		if(pred( vTSD[ mTSD[q.front()] ] ) ){
			found = q.front();
			break;
		}
		std::list<std::string> adjs = adjacencyList[ mTSD[q.front()] ];
		for(std::string s  : adjs){
			//see if this place has been visited
			if(prevMap.find(s) == prevMap.end()){	//not visited
				//push adjacencies onto q
				q.push(s);
				//map the adjacencies into prevMap
				prevMap[s] = std::pair<std::string, int>(q.front(), prevMap[q.front()].second+1);
			}
		}
		//forgot the pop...
		q.pop();
	}
	//build the syop-by-stop directions
	std::list<std::string> resTSD;
	resTSD.push_front(found);
	while(resTSD.front() != a){
		resTSD.push_front( prevMap[ resTSD.front() ].first );
	}

	return resTSD;
}